#pragma once

#include "VLNRecevierImpl.h"

template <typename ReturnT, typename ParamT>
class CVLNObserverImplBase
{
public:
	virtual void AddReceiver(CVLNReceiverImplBase<ReturnT, ParamT>* receiver) = 0;
	virtual void RemoveReceiver(CVLNReceiverImplBase<ReturnT, ParamT>* receiver) = 0;
	virtual ReturnT Broadcast(ParamT param) = 0;
	virtual ReturnT Notify(ParamT param) = 0;
};

template <typename ReturnT, typename ParamT>
class CVLNObserverImpl : public CVLNObserverImplBase<ReturnT, ParamT>
{
public:
	CVLNObserverImpl()
		: count_(0)
	{}

	virtual ~CVLNObserverImpl()	{}

	virtual void AddReceiver(CVLNReceiverImplBase<ReturnT, ParamT>* receiver)
	{
		if (receiver == NULL)
			return;

		receivers_[count_] = receiver;
		receiver->AddObserver(this);
		count_++;
	}

	virtual void RemoveReceiver(CVLNReceiverImplBase<ReturnT, ParamT>* receiver)
	{
		if (receiver == NULL)
			return;

		ReceiversMap::iterator it = receivers_.begin();
		for (; it != receivers_.end(); ++it)
		{
			if (it->second == receiver)
			{
				receivers_.erase(it);
				break;
			}
		}
	}

	virtual ReturnT Broadcast(ParamT param)
	{
		ReceiversMap::iterator it = receivers_.begin();
		for (; it != receivers_.end(); ++it)
		{
			it->second->Receive(param);
		}

		return ReturnT();
	}

	virtual ReturnT Notify(ParamT param)
	{
		ReceiversMap::iterator it = receivers_.begin();
		for (; it != receivers_.end(); ++it)
		{
			it->second->Respond(param, this);
		}

		return ReturnT();
	}

protected:
	typedef std::map<int, CVLNReceiverImplBase<ReturnT, ParamT>*> ReceiversMap;
	ReceiversMap receivers_;
	int count_;
};
